﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using LitJson;
using System.Drawing;
using System.Drawing.Imaging;

namespace point2bmp
{
    public class MyVector3
    {
        public float x;
        public float y;
        public float z;
    }

    public class MyPoint
    {
        public int x;
        public int y;
    }
    public class PathNode
    {
        // 二维数组中的位置
        public int Idx;
        public int Idy;

        public MyVector3 WorldPos;
        public List<PathNode> Neighbours;
        public int TempUseCount;
    }
    public delegate PathNode FindPathNodeFunc(int x, int y);


    public partial class main
    {
        // 配置信息
        static string basepath = "../../../../";
        static string filename = "points(1).json";
        static string outdir = "2017-11-26-1/";
        static string moddir = "2017-11-26-1/";
        static int width = 20000;    // 图片大小，暗指凤凰山大小=width/cellcount/scalepoint
        static int height = 20000;
        static int cellcount = width / 50;   // 横纵各有多少个单元。 每个小单元的大小为width/cellcount（单元大小 暗指5米一个步长）
        static float scalepoint = 1 / 5.0f;   // n:1 scale orignal point.


        static int cellwidth = width / cellcount;
        static int cellheight = height / cellcount;
        static PathNode[,] cellMap = null;

        static void Main(string[] args)
        {
            Directory.CreateDirectory(basepath + outdir);

            ReadPoints();

            // 根据路点自动生成图片
            Point2Pic();           
            
            // 处理手动修改后的图片
            ModPic2Point();

            // 测试寻路。
            //TestAStar();
        }
        static void ReadPoints()
        {
            cellMap = new PathNode[cellcount, cellcount];

            var points = loadObjectFromJsonFile<List<MyVector3>>(basepath + filename);
            Console.WriteLine(points == null ? 0 : points.Count);
            
            // jiang dian ying she yi xia
            float maxx = Single.MinValue, minx = Single.MaxValue;
            float maxy = Single.MinValue, miny = Single.MaxValue;
            foreach (var it in points)
            {
                if (maxx < it.x)
                    maxx = it.x;
                if (minx > it.x)
                    minx = it.x;
                if (maxy < it.z)
                    maxy = it.z;
                if (miny > it.z)
                    miny = it.z;
            }
            if (Math.Abs(maxy - miny) * scalepoint > cellcount
                || Math.Abs(maxx - minx) * scalepoint > cellcount)
            {
                Console.WriteLine("error.");
            }

            // 将所有的点，映射到二维数组中
            foreach (var it in points)
            {
                var point = MapToCell(it);
                int itx = point.x;//(int)((it.x * scalepoint + cellcount / 2));
                int ity = point.y;//(int)((it.z * scalepoint + cellcount / 2));
                if (itx < cellcount && ity < cellcount && itx >= 0 && ity >= 0)
                    cellMap[itx, ity] = new PathNode() { WorldPos = it, Neighbours = new List<PathNode>(), Idx = itx, Idy = ity };
            }            
            

        }

        static MyPoint MapToCell(MyVector3 point)
        {
            var it = point;
            int itx = (int)((it.x * scalepoint + cellcount / 2));
            int ity = (int)((it.z * scalepoint + cellcount / 2));
            return new MyPoint() {x = itx, y = ity};
        }

        static void Point2Pic()
        {                       
            Console.WriteLine(1);

            Console.WriteLine(Directory.GetCurrentDirectory());

            DrawCellToPng("");
            
            Console.WriteLine("step1 over");

            Pic2All();
        }
        static void DrawCellToPng(string tag)
        {
            // Image img = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);            
            Image img = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            Graphics g = Graphics.FromImage(img);
            Pen pen = new Pen(Color.Gray);
            //g.FillRectangle(pen.Brush, 0, 0, 10, 10);

            // huizhiqipange.
            for (int i = 0; i < cellcount; i++)
            {
                for (int j = 0; j < cellcount; j++)
                {
                    g.DrawRectangle(pen, i * cellwidth, j * cellheight, cellwidth, cellheight);
                }
            }

            // 绘制所有离散的点
            Pen redpen = new Pen(Color.Red);
#if false
            foreach (var it in points)
            {
                int itx = (int)((it.x * scalepoint + cellcount / 2)) * cellwidth;
                int ity = (int)((it.z * scalepoint + cellcount / 2)) * cellheight;
                g.FillRectangle(redpen.Brush, itx,ity,cellwidth,cellheight);
            }
#else
            for (int i = 0; i < cellcount; i++)
            {
                for (int j = 0; j < cellcount; j++)
                {
                    var it = cellMap[i, j];
                    if (it != null)
                    {
                        g.FillRectangle(redpen.Brush, it.Idx * cellwidth, it.Idy * cellheight, cellwidth, cellheight);
                    }
                }
            }
#endif

            // 画中心点。
            Pen centerpen = new Pen(Color.Black);
            g.FillRectangle(centerpen.Brush, cellcount / 2 * cellwidth, cellcount / 2 * cellheight, cellwidth, cellheight);

            img.Save(basepath + outdir + tag + "1.png", ImageFormat.Png);
        }

        public static bool IsValidIndex(int i, int max)
        {
            return (i >= 0 && i <= max);
        }

        public static T ToObject<T>(string json)
        {
            return JsonMapper.ToObject<T>(json);
        }


        static public T loadObjectFromJsonFile<T>(string path)
        {
            //             try
            //             {
            TextReader reader = new StreamReader(path);
            if (reader == null)
            {
                reader.Close();
                return default(T);
            }

            T data = ToObject<T>(reader.ReadToEnd());
            if (data == null)
            {
            }

            reader.Close();

            return data;
            //             }
            //             catch (System.Exception e)
            //             {
            //                 return default(T);
            //             }

        }

    }
}